# 前言
<Suspense> 是一个内置组件,用来在组件树中协调对异步依赖的处理。可以帮助我们更好的完成组件树父组件对子组件的多个嵌套异步依赖关系的管理,当父组件处于等待中时,允许我们自定挂载一个加载中状态。

上图中,红色字体代表的是组件有异步的 setup() 。 通过 <Suspense> 组件我们可以很容易实现在组件异步加载时统一展示加载中状态,在所有组件完成加载时,再统一展示:
html
复制代码<Suspense>
<!-- 具有深层异步依赖的组件 -->
<Dashboard />
<!-- 在 #fallback 插槽中显示 “正在加载中” -->
<template #fallback>
Loading...
</template>
</Suspense>
@前端进阶之旅: 代码已经复制到剪贴板
接下来我们将深度解读 <Suspense> 组件实现的原理。
# Suspense 挂载
<Suspense> 组件和所有内置组件一样,也是有初始化挂载的过程,先来看看 Vue 对 <Suspense> 组件的源码定义:
export const SuspenseImpl = {
name: 'Suspense',
// Suspense 组件标识符
__isSuspense: true,
process(...) {
if (n1 == null) {
// 初始化挂载的逻辑
} else {
// diff 的逻辑
}
},
create: createSuspenseBoundary,
normalize: normalizeSuspenseChildren
}
@前端进阶之旅: 代码已经复制到剪贴板
process 的执行时机和前面提到的 <Teleport> 组件是一致的,会在 patch 的时候根据组件的 shapeFlag 标志来判断是否需要执行 process 函数的调用。
const patch = (n1, n2, container, anchor, ...) => {
// ...
const { type, ref, shapeFlag } = n2
switch (type) {
// 根据 type 类型处理
case Text:
// 对文本节点的处理
processText(n1, n2, container, anchor)
break
// 这里省略了一些其他节点处理,比如注释、Fragment 节点等等
// ...
default:
// 根据 shapeFlag 来处理
// ...
else if (__FEATURE_SUSPENSE__ && shapeFlag & ShapeFlags.SUSPENSE) {
// 对 Suspense 节点进行处理
type.process(
n1,
n2,
container,
